﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Windows;
using InnvoiceActual.BaseDeDatos.innvoicedbDataSetTableAdapters;
using InnvoiceActual.Logica.GestorObject;
using InnvoiceActual.Logica.GestorObject.Remito;
using MySql.Data.MySqlClient;

namespace InnvoiceActual.Logica.GestorDB.RemitoDB
{
    public class RemitoDB
    {
        #region Property

        EmpresaCS empresa = EmpresaCS.Instance;
        ClienteDB clienteDB = new ClienteDB();

        #endregion

        #region CRUD Methods

        public void AddRemito(Remito remito)
        {
            int resultadoConsulta;
            
            remitoTableAdapter remitoTB = new remitoTableAdapter();
            
            remitoTB.Connection.Open();
            MySqlTransaction transaccion = remitoTB.Connection.BeginTransaction();

            try
            {
                int codigoEmpresa = empresa.CodigoEmpresa;
                int nroComprobante1 = empresa.NroComprabante1;
                int nroComprobante2 = remito.NroComprobante2;
                byte codigoTipo = remito.CodigoTipo;
                DateTime fecha = remito.Fecha;
                bool anulada = remito.Anulada;
                bool impresa = remito.Impresa;
                bool estado = remito.Estado;

                
                
                
                resultadoConsulta = remitoTB.InsertRemito(codigoEmpresa, (short)nroComprobante1, nroComprobante2, codigoTipo, fecha, anulada, impresa, estado);
                
               

                transaccion.Commit();

                if (resultadoConsulta == 1)
                {
                    MessageBox.Show("Operacion de inserción exitosa", "Información", MessageBoxButton.OK);
                }
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error AddRemito - RemitoDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                remitoTB.Connection.Close();
            }
        }

        public Remito ObtenerRemitoPorCodigo(short nro1, int nro2, byte tipo)
        {
            Remito resultado = new Remito();

            remitoTableAdapter remitoTB = new remitoTableAdapter();

            remitoTB.Connection.Open();
            MySqlTransaction transaccion = remitoTB.Connection.BeginTransaction();

            try
            {
                int codigoEmpresa = empresa.CodigoEmpresa;

                DataTable resultadoConsulta = remitoTB.GetDataByObtenerRemitoPorCodigo(codigoEmpresa, nro1, nro2, tipo);

                if (resultadoConsulta.Rows.Count > 0)
                {
                    foreach (DataRow item in resultadoConsulta.Rows)
                    {
                        resultado.CodigoEmpresa = Convert.ToInt16(item["codigo_empresa"].ToString());
                        resultado.NroComprobante1 = Convert.ToInt16(item["nro_comprobante1"].ToString());
                        resultado.NroComprobante2 = Convert.ToInt16(item["nro_comprobante2"].ToString());
                        resultado.CodigoTipo = Convert.ToByte(item["codigoTipo"]);

                        resultado.Fecha = Convert.ToDateTime(item["fecha"]);
                        resultado.FechaString = Convert.ToDateTime(item["fecha"]).ToShortDateString();
                        resultado.Comprobante = resultado.NroComprobante1.ToString("D4") + "-" + resultado.NroComprobante2.ToString("D8");
                        resultado.Total = CalcularTotal(codigoEmpresa, resultado.NroComprobante1, resultado.NroComprobante2, resultado.CodigoTipo);
                        resultado.TotalString = resultado.Total.ToString("C", new System.Globalization.CultureInfo("en-US"));

                        resultado.Anulada = Convert.ToBoolean(item["anulada"]);
                        resultado.Impresa = Convert.ToBoolean(item["impresa"]);
                        resultado.Estado = Convert.ToBoolean(item["estado"]);

                    }
                }
                else
                {
                    resultado.NroComprobante1 = -1;
                    resultado.NroComprobante2 = -1;
                }
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error ObtenerRemitoPorCodigo(short nro1, int nro2, int tipo) - RemitoDB --> " + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                remitoTB.Connection.Close();
            }

            return resultado;
        }

        //Actualizar el remito
        private int UpdateRemito(int nro1, int nro2, int tipo, DateTime fecha, bool anulada, bool impresa, bool estado)
        {

            int resultadoConsulta = 0;

            remitoTableAdapter remitoTB = new remitoTableAdapter();

            remitoTB.Connection.Open();

            MySqlTransaction transaccion = remitoTB.Connection.BeginTransaction();

            try
            {
                int codigoEmpresa = empresa.CodigoEmpresa;

                resultadoConsulta = remitoTB.UpdateRemito(fecha, anulada, impresa, estado, codigoEmpresa, (short)nro1, nro2, tipo);
                transaccion.Commit();
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error UpdateRemito - RemitoDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                remitoTB.Connection.Close();
            }

            return resultadoConsulta;
        }

        #endregion

        #region Methods

        //Debo decirle para que tipo de remito lo requiero
        public int GetProximoNumeroRemito(int codigoRemito)
        {

            remitoTableAdapter remitoTB = new remitoTableAdapter();

            ConfigRemitoDB configRemitoDB = new ConfigRemitoDB();

            int max_nroRegistro2 = 0;

            int numConfigRemito = configRemitoDB.GetNumeracionDeConfigRemito(codigoRemito);

            int cantRemitosGenerados = CantidadRemitosGenerados();

            if (numConfigRemito == cantRemitosGenerados)
            {
                max_nroRegistro2 = numConfigRemito + 1;
            }
            else
            {
                max_nroRegistro2 = cantRemitosGenerados + 1;

                configRemitoDB.IncrementarNumeracionDeRemito(codigoRemito, cantRemitosGenerados); 
            }

            return max_nroRegistro2;
           
        }

        private int CantidadRemitosGenerados()
        {
            remitoTableAdapter remitoTB = new remitoTableAdapter();

            int resultado = 0;

            remitoTB.Connection.Open();
            MySqlTransaction transaccion = remitoTB.Connection.BeginTransaction();

            try
            {
                DataTable resultadoConsulta = remitoTB.GetData();

                if (resultadoConsulta.Rows.Count > 0)
                {
                    resultado = resultadoConsulta.Rows.Count;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " Error -- Class RemitoDB -- Methods CantidadRemitosGenerados()", "Cuidado", MessageBoxButton.OK);
                transaccion.Rollback();
            }
            finally
            {
                remitoTB.Connection.Close();
            }

            return resultado;
        }

        //True para PENDIENTES, False para FACTURADOS
        public List<Remito> ObtenerRemitosParaListar(bool pendienteFacturado)
        {
            List<Remito> resultados = new List<Remito>();
            resultados.Clear();

            int codigoEmpresa = empresa.CodigoEmpresa;

            remitoTableAdapter remitoTB = new remitoTableAdapter();

            remitoTB.Connection.Open();
            MySqlTransaction transaccion = remitoTB.Connection.BeginTransaction();

            try
            {
                DataTable remitosConsulta = new DataTable();

                if (pendienteFacturado)
                {
                    remitosConsulta = remitoTB.GetDataByListadoRemitosPendientes_O_Facturados(codigoEmpresa, 0);
                }
                else
                {
                    remitosConsulta = remitoTB.GetDataByListadoRemitosPendientes_O_Facturados(codigoEmpresa, 1);
                }

                if (remitosConsulta.Rows.Count > 0)
                {
                    foreach (DataRow item in remitosConsulta.Rows)
                    {
                        Remito remito = new Remito();

                        remito.CodigoEmpresa = Convert.ToInt16(item["codigo_empresa"].ToString());
                        remito.NroComprobante1 = Convert.ToInt16(item["nro_comprobante1"].ToString());
                        remito.NroComprobante2 = Convert.ToInt16(item["nro_comprobante2"].ToString());
                        remito.CodigoTipo = Convert.ToByte(item["codigoTipo"].ToString());

                        remito.Fecha = Convert.ToDateTime(item["fecha"]);
                        remito.FechaString = Convert.ToDateTime(item["fecha"]).ToShortDateString();
                        remito.Comprobante = remito.NroComprobante1.ToString("D4") + "-" + remito.NroComprobante2.ToString("D8");
                        remito.Cliente.RazonSocial = item["clienteRazonSocial"].ToString().ToUpper();
                        remito.Total = CalcularTotal(codigoEmpresa, remito.NroComprobante1, remito.NroComprobante2, remito.CodigoTipo);
                        remito.TotalString = remito.Total.ToString("C",new System.Globalization.CultureInfo("en-US"));

                        resultados.Add(remito);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " Error -- Class RemitoDB -- Methods ObtenerRemitosParaListar()", "Cuidado", MessageBoxButton.OK);
                transaccion.Rollback();
            }
            finally
            {
                remitoTB.Connection.Close();
            }

            return resultados;
        }

        public int UpdateRemito(Remito remito)
        {
            return UpdateRemito(remito.NroComprobante1, remito.NroComprobante2, remito.CodigoTipo, remito.Fecha, remito.Anulada, remito.Impresa, remito.Estado);
        }

        #endregion

        #region Auxiliar Methods

        private double CalcularTotal(int codigoEmpresa, int nroRemito1, int nroRemito2, byte tipo)
        {
            double resultado = 0;

            pie_remitoTableAdapter pieRemitoTB = new pie_remitoTableAdapter();

            try
            {
                DataTable resultadoConsulta = pieRemitoTB.GetDataByCalcultarTotalRemito(codigoEmpresa, (short)nroRemito1, nroRemito2,tipo);

                if (resultadoConsulta.Rows.Count > 0)
                {
                    foreach (DataRow item in resultadoConsulta.Rows)
                    {
                        double subTotal = Convert.ToDouble(item["subtotal"].ToString());
                        double bonificacion = Convert.ToDouble(item["bonificacion"].ToString());

                        resultado = subTotal + ((subTotal * bonificacion) / 100);

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " Error -- Class ReciboDB -- Methods CalcularTotal(int codigoEmpresa, int nroRemito1, int nroRemito2)", "Cuidado", MessageBoxButton.OK);
            }

            return resultado;
        }

        #endregion
    }
}